package com.janlei.tdd.practise;

import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Getter
@Setter
@NoArgsConstructor
public abstract class Unit implements UnitHelper {
    protected int number;
}


interface UnitHelper {
    /**
     * 单位转换
     *
     * @param clazz clazz
     * @return {@link T}
     */
    <T extends Unit> T transfer(Class<T> clazz);
}


@Getter
@Setter
@NoArgsConstructor
class Foot extends Yard {

    @Override
    public <T extends Unit> T transfer(Class<T> clazz) {
        if (this.getClass().equals(clazz)) {
            return (T) this;
        }
        if (Inch.class.equals(clazz)) {
            int number = this.getNumber();
            int capital = number * 12;
            Inch inch = new Inch();
            inch.setNumber(capital);
            return (T) inch;
        }

        return check(clazz);
    }
}

@Getter
@Setter
@NoArgsConstructor
class Inch extends Foot {
    @Override
    public <T extends Unit> T transfer(Class<T> clazz) {
        if (this.getClass().equals(clazz)) {
            return (T) this;
        }
        return check(clazz);
    }
}

@Getter
@Setter
@NoArgsConstructor
class Yard extends Unit {

    @Override
    public <T extends Unit> T transfer(Class<T> clazz) {
        if (this.getClass().equals(clazz)) {
            return (T) this;
        }

        if (Foot.class.equals(clazz)) {
            int number = this.getNumber();
            int capital = number * 3;
            Foot foot = new Foot();
            foot.setNumber(capital);
            return (T) foot;
        }

        if (Inch.class.equals(clazz)) {
            int number = this.getNumber();
            int capital = number * 3 * 12;
            Inch inch = new Inch();
            inch.setNumber(capital);
            return (T) inch;
        }
        return check(clazz);
    }

    <T extends Unit> T check(Class<T> clazz) {
        throw new IllegalArgumentException("不支持转换类型：" + clazz.getSimpleName());
    }
}
